package com.kaifamiao.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;

@WebFilter( urlPatterns = "/*" ,
            initParams = { @WebInitParam( name="exclude" , value = "/index.html,/sign/in" ) })
public class SignInFilter implements Filter {

    private Logger logger = Logger.getLogger( this.getClass().getName() );

    private Set<String> excludes ;

    @Override
    public void init( FilterConfig config ) throws ServletException {
        logger.info( "初始化" );
        // 从初始化参数中获取被排除的路径
        String exclude = config.getInitParameter( "exclude" );
        // 若 exclude 即不是 null 也不是 空串
        if( exclude != null && !exclude.trim().isEmpty() ){
            excludes = new HashSet<>();
            // 如果 exclude 中含有逗号
            if( exclude.contains( "," ) ){
                String[] array = exclude.split(",");
                // List<String> list = Arrays.asList( array ); // Java 9 以前
                List<String> list = List.of(array); // Java 9
                excludes.addAll(list);
                return ;
            }
            excludes.add( exclude );
        }
    }

    @Override
    public void doFilter( ServletRequest req , ServletResponse resp , FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req ;
        HttpServletResponse response = (HttpServletResponse)resp ;
        String uri = request.getRequestURI();
        DispatcherType type = request.getDispatcherType();
        logger.info( "执行过滤[" + type + "]" + uri );

        Object value = request.getSession().getAttribute( "username" );
        // 若从会话中根据 username 获取到 String 类型的参数值
        if( value instanceof String uname ) {
            logger.info( "[" + uname + "]已登录" );
            // 将请求和响应向后传递
            chain.doFilter( req , resp );
            return ;
        }

        // 如果被访问的 uri 在 excludes 中是存在，则需要忽略对该请求的拦截
        if( excludes.contains( uri ) ){
            chain.doFilter( req , resp );
            return ;
        }

        logger.info( "因为未登录，所以禁止访问 " + uri + " ，即将跳转到首页");
        response.sendRedirect( "/index.html" );
    }

    @Override
    public void destroy() {
        logger.info( "销毁" );
    }
}
